package org.infodavid.common.pool;

import java.io.Serializable;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * The Class AbstractPooledFactory.
 * @param <T>
 */
public abstract class AbstractPooledFactory<T extends Serializable> {

	/** The Constant LOGGER. */
	private static final Log LOGGER = LogFactory.getLog(AbstractPooledFactory.class);

	/**
	 * Instantiates a new abstract factory.
	 */
	protected AbstractPooledFactory() {
		super();
	}

	/**
	 * Borrow.
	 * @return the new object or borrowed one
	 */
	protected abstract T doBorrow();

	/**
	 * Borrow.
	 * @return the new object or borrowed one
	 */
	public final T borrow() {
		final long start = System.currentTimeMillis();

		try {
			return doBorrow();
		}
		finally {
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("Object built in " + (System.currentTimeMillis() - start));
			}
		}
	}

	/**
	 * Invalidate.
	 * @param obj the object to invalidate
	 */
	protected abstract void doInvalidate(final T obj);

	/**
	 * Invalidate.
	 * @param obj the object to invalidate
	 */
	public final void invalidate(final T obj) {
		final long start = System.currentTimeMillis();

		try {
			doInvalidate(obj);
		}
		finally {
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("Object invalidated in " + (System.currentTimeMillis() - start));
			}
		}
	}

	/**
	 * Release.
	 * @param obj the object to release to pool
	 */
	protected abstract void doRelease(final T obj);

	/**
	 * Release.
	 * @param obj the object to release to pool
	 */
	public final void release(final T obj) {
		final long start = System.currentTimeMillis();

		try {
			doRelease(obj);
		}
		finally {
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("Object released in " + (System.currentTimeMillis() - start));
			}
		}
	}
}
